from Forum.handler import RedisHandler
from datetime import datetime
from tornado.web import authenticated
from playhouse.shortcuts import model_to_dict
from apps.utils.decorators import authenticated_async
from apps.question.forms import *
from apps.question.models import *
import aiofiles
import json
import uuid
import os
from apps.utils.util_func import json_serial



class QuestionHandler(RedisHandler):
    @authenticated_async
    async def get(self, *args, **kwargs):
        question_list = []
        try:
            questions_query = Question.extend()

            c = self.get_argument("c", None)
            if c:
                questions_query = questions_query.filter(Question.category == c)

            order = self.get_argument("o", None)
            if order:
                if order == 'new':
                    questions_query = questions_query.order_by(-Question.add_time)
                elif order == "hot":
                    questions_query = questions_query.order_by(-Question.answer_nums)


            questions = await self.application.objects.execute(questions_query)

            for question in questions:
                item_dict = {
                    "user": {
                        "id": question.user.id,
                        "nick_name": question.user.nickname
                    },
                    "id": question.id,
                    "title": question.title,
                    "content": question.content,
                    "answer_nums": question.answer_nums,
                }
                question_list.append(item_dict)

        except Question.DoesNotExist as e:
            self.set_status(404)

        self.finish(json.dumps(question_list))

    @authenticated_async
    async def post(self, *args, **kwargs):
        re_data = {}
        form = QuestionForm(self.request.body_arguments)
        if form.validate():
            files_meta = self.request.files.get("image", None)
            if not files_meta:
                self.set_status(400)
                re_data["image"] = "请上传图片"
            else:
                # uuid生成文件名
                new_filename = ''
                for meta in files_meta:
                    filename = meta['filename']
                    new_filename = "{uuid}_{filename}".format(uuid=uuid.uuid1(), filename=filename)
                    file_path = os.path.join(self.settings["MEDIA_ROOT"], new_filename)
                    async with aiofiles.open(file_path, 'wb') as f:
                        await f.write(meta["body"])

                question = await self.application.objects.create(
                    Question,
                    user=self.current_user,
                    category=form.category.data,
                    title=form.title.data,
                    content=form.content.data,
                    image = new_filename
                )
                re_data["id"] = question.id

        else:
            self.set_status(400)
            for field in form.errors:
                re_data[field] = form.errors[field][0]

        self.finish(re_data)

class QuestionDetailHandler(RedisHandler):
    @authenticated_async
    async def get(self, question_id, *args, **kwargs):
        re_data = {}
        try:
            question_details = await self.application.objects.execute(Question.extend().where(Question.id==int(question_id)))
            for data in question_details:
                item_dict = model_to_dict(data)
                re_data = item_dict

        except Question.DoesNotExist as e:
            self.set_status(404)

        self.finish(json.dumps(re_data, default=json_serial))


class QuestionAnswerHandler(RedisHandler):

    @authenticated_async
    async def get(self, question_id, *args, **kwargs):
        re_data = []
        try:
            question = await self.application.objects.get(Question, id=int(question_id))
            question_answers = await self.application.objects.execute(
                Answer.extend().where(Answer.question==question, Answer.parent_answer.is_null(True)).order_by(Answer.add_time.desc())
            )

            for item in question_answers:
                item_dict = {
                    "user": {
                        "id": self.current_user.id,
                        "nick_name": self.current_user.nickname,
                    },
                    "id": item.id,
                    "content": item.content,
                    "reply_nums": item.reply_nums,
                }

                re_data.append(item_dict)
        except Question.DoesNotExist as e:
            self.set_status(404)

        self.finish(json.dumps(re_data))

    @authenticated_async
    async def post(self, question_id, *args, **kwargs):
        re_data = {}
        param = self.request.body.decode("utf8")
        param = json.loads(param)
        form = QuestionAnswerForm.from_json(param)
        if form.validate():
            try:
                question = await self.application.objects.get(Question, id=int(question_id))
                question_answer = await self.application.objects.create(
                    Answer,
                    user=self.current_user,
                    question=question,
                    content=form.content.data,
                )
                question.answer_nums += 1
                await self.application.objects.update(question)
                re_data["id"] = question_answer.id
                re_data["user"] = {
                    "id": self.current_user.id,
                    "nick_name": self.current_user.nickname
                }
            except Question.DoesNotExist as e:
                self.set_status(404)
        else:
            self.set_status(400)
            for field in form.errors:
                re_data[field] = form.errors[field][0]

        self.finish(re_data)


#
# class AnswerReplyHandler(RedisHandler):
#
#     @authenticated_async
#     async def get(self, comment_id, *args, **kwargs):
#         re_data = []
#         comment_replys = await self.application.objects.execute(
#             PostComment.extend().where(PostComment.parent_comment_id==int(comment_id))
#         )
#         for item in comment_replys:
#             item_dict = {
#                 "user": {
#                     "id":item.user.id,
#                     "nick_name": item.user.nickname
#                 },
#                 "content": item.content,
#                 "reply_nums": item.reply_nums,
#                 "add_time": item.add_time.strftime("%Y-%m-%d"),
#                 "id": item.id
#             }
#             re_data.append(item_dict)
#         self.finish(json.dumps(re_data,default=json_serial))
#
#     @authenticated_async
#     async def post(self, comment_id, *args, **kwargs):
#         #添加回复
#         re_data = {}
#         param = self.request.body.decode("utf8")
#         param = json.loads(param)
#         form = CommentReplyForm.from_json(param)
#         if form.validate():
#             try:
#                 #获取post_id的值填入数据库
#                 post_id = 0
#                 comment = await self.application.objects.get(PostComment, id=int(comment_id))
#
#                 #查到该条父评论对应的文章ID
#                 post_query = PostComment.select().where(PostComment.id==comment.id)
#                 post = await self.application.objects.execute(post_query)
#                 for p in post:
#                     post_id = p.post_id
#                 #注意！！
#
#                 replyed_user = await self.application.objects.get(User, id=form.replyed_user.data)
#                 reply = await self.application.objects.create(
#                     PostComment,
#                     user=self.current_user,
#                     parent_comment=comment,
#                     reply_user=replyed_user,
#                     content=form.content.data,
#                     post_id=post_id,#必须填入这个字段
#                 )
#                 comment.reply_nums += 1
#                 await self.application.objects.update(comment)
#                 re_data["id"] = reply.id
#                 re_data["user"] = {
#                     "id": self.current_user.id,
#                     "nick_name": self.current_user.nickname
#                 }
#
#
#             except PostComment.DoesNotExist as e:
#                 self.set_status(404)
#
#             except User.DoesNotExist as e:
#                 self.set_status(400)
#                 re_data["replyed_user"] = "用户不存在"
#         else:
#             self.set_status(400)
#             for field in form.errors:
#                 re_data[field] = form.errors[field][0]
#
#         self.finish(re_data)
